package com.diaohw.platform.utility.netty.ws;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketClientProtocolHandler;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
import io.netty.handler.timeout.IdleStateHandler;

import java.net.URI;
import java.util.concurrent.TimeUnit;

public class WebSocketClient {
    private final URI uri;
    private Channel channel;
    private EventLoopGroup group;
    private final int heartbeatInterval = 30; // 心跳间隔(秒)

    public WebSocketClient(URI uri) {
        this.uri = uri;
    }

    public void connect() throws Exception {
        group = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ChannelPipeline pipeline = ch.pipeline();

                            // HTTP编解码器
                            pipeline.addLast(new HttpClientCodec());
                            // HTTP聚合器(将多个HTTP消息聚合为一个FullHttpRequest/Response)
                            pipeline.addLast(new HttpObjectAggregator(8192));

                            // WebSocket协议处理器
                            pipeline.addLast(new WebSocketClientProtocolHandler(
                                    uri, WebSocketVersion.V13, null, false, new DefaultHttpHeaders(), 10000));

                            // 心跳检测(读空闲触发)
                            pipeline.addLast(new IdleStateHandler(heartbeatInterval, 0, 0, TimeUnit.SECONDS));
                            // 自定义心跳处理器
                            pipeline.addLast(new HeartbeatHandler());

                            // 业务消息处理器
                            pipeline.addLast(new WebSocketClientHandler());
                        }
                    });

            // 连接服务器
            ChannelFuture future = bootstrap.connect(uri.getHost(), getPort()).sync();
            channel = future.channel();
            System.out.println("WebSocket客户端已连接: " + uri);

            // 等待连接关闭
            channel.closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }

    private int getPort() {
        if (uri.getPort() == -1) {
            return uri.getScheme().equals("wss") ? 443 : 80;
        }
        return uri.getPort();
    }

    public void sendMessage(String message) {
        if (channel != null && channel.isActive()) {
            channel.writeAndFlush(new TextWebSocketFrame(message));
        } else {
            System.err.println("连接未建立，无法发送消息");
        }
    }

    public void disconnect() {
        if (channel != null) {
            channel.close();
        }
        group.shutdownGracefully();
    }

    public static void main(String[] args) throws Exception {
        URI uri = new URI("ws://127.0.0.1:38838/api/v1/data-socket/getModelData?pushType=realtime"); // 替换为你的WebSocket服务器地址
        WebSocketClient client = new WebSocketClient(uri);

        // 添加关闭钩子
        Runtime.getRuntime().addShutdownHook(new Thread(client::disconnect));

        client.connect();

        // 示例：发送测试消息(实际应用中可通过其他方式触发)
        // client.sendMessage("Hello, WebSocket!");
    }
}